package network.dataFormats;
import java.util.Arrays;

import network.protocol.PackageSplitter;
public class NetworkPackage {
	public final static int HEADERSIZE = 12;
	// The type of package
	public PackageHeader header;
	// The data (including the header in the first HEADERSIZE bytes)
	public byte[] bytes;
	// When the package is created from code a header and data is given, we need
	// to add the body to the data.
	public NetworkPackage(PackageType type, byte[] body, int id, float time) {
		this.header = new PackageHeader(type, id, time);
		bytes = new byte[body.length + HEADERSIZE];
		// write data in the of the array (from HEADERSIZE to the end)
		System.arraycopy(body, 0, bytes, HEADERSIZE, body.length);
		// write header in the beginning (from 0 to HEADERSIZE-1)
		writeHeader();
	}
	// When the package is created from the data input across the network, only
	// data is given, read out the header from that.
	public NetworkPackage(byte[] data) {
		this.bytes = data;
		this.header = readHeader();
	}
	private PackageHeader readHeader() {
		return new PackageHeader(Arrays.copyOfRange(bytes, 0, HEADERSIZE));
	}
	private void writeHeader() {
		byte[] headerBytes = header.toBytes();
		assert (headerBytes.length == HEADERSIZE);
		System.arraycopy(headerBytes, 0, bytes, 0, headerBytes.length);
	}
	@Override
	public String toString() {
		if (header.type == PackageType.SPLIT) {
			return header.type + " " + bytes.length + " " + PackageSplitter.getId(this) + " " + PackageSplitter.getIndex(this) + " " + PackageSplitter.getSize(this);
		}
		return header.type + " " + bytes.length + " bytes";
	}
	/**
	 * Returns the type that is specified in the header (INIT, ADDB, ADDG, ...)
	 * 
	 * @author toni
	 * 
	 * @return
	 */
	public PackageType getType() {
		return header.type;
	}
	/**
	 * Returns the data contained in this package. Does not return all bytes (the data that would be sent through the network) but instead only the game-relevant bytes (without the header)
	 * 
	 * @author toni
	 * 
	 * @return
	 */
	public byte[] getData() {
		return Arrays.copyOfRange(bytes, HEADERSIZE, bytes.length);
	}
	public int getSize() {
		return bytes.length;
	}
	public Object getTime() {
		// TODO Auto-generated method stub
		return null;
	}
}
